using System;

using Slaks.Descriptions;

namespace Slaks.Filters
{
  /// <summary>
  /// ArabTermFilter - implements basic parsing, which filters all the characters 
  /// (including punctuation) except for arab letters
  /// </summary>
  [ModuleDescriptionAttribute("Arabic character filter","Slava Kisilevich")]
	public class ArabTermFilter : AFilter
	{
    protected static readonly int ArabNotInRangeBegin_1 = 0x600;
    protected static readonly int ArabNotInRangeEnd_1 = 0x620;

    protected static readonly int ArabNotInRangeBegin_2 = 0x64B;
    protected static readonly int ArabNotInRangeEnd_2 = 0x658;

    protected static readonly int ArabNumbersBegin = 0x660;
    protected static readonly int ArabNumbersEnd = 0x6FF;

    protected static readonly int ArabQashida = 0x640;
    
    protected static readonly int ArabLastLetterToReplace1 = 0x622;
    protected static readonly int ArabLastLetterToReplace2 = 0x623;
    protected static readonly int ArabLastLetterToReplace3 = 0x625;
    protected static readonly int ArabLastLetterReplaced1_2_3 = 0x627;

    protected static readonly int ArabLastLetterToReplace4 = 0x624;
    protected static readonly int ArabLastLetterReplaced4 = 0x648;

    protected static readonly int ArabLastLetterToReplace5 = 0x629;
    protected static readonly int ArabLastLetterReplaced5 = 0x647;

		protected static readonly int ArabicMiddleOfSentencePunctuationMarksComma = 0x060c;
		protected static readonly int ArabicEndOfSentencePunctuationMarkQuestion = 0x061f;

    public ArabTermFilter() {}

    /// <summary>
    /// </summary>
    /// <param name="ch">character to check</param>
    /// <returns>true/false</returns>
    public override bool IsWhiteSpace(char ch)
    {
      if (ch <= ArabNotInRangeBegin_1) return true;
      if (ch >= ArabNumbersBegin && ch <= ArabNumbersEnd) return true;
      if (ch > ArabNumbersEnd) return true;

      return false;
    }

		public override bool IsMiddleSentencePunctuationMark(char ch)
		{
			if (
				ch == ArabicMiddleOfSentencePunctuationMarksComma ||
				ch == GeneralMiddleOfSentencePunctuationMarkComma
				) return true;

			return false;
		}

		public override bool IsEndOfSentencePunctuationMark(char ch)
		{
			if (ch == ArabicEndOfSentencePunctuationMarkQuestion || 
				ch == GeneralEndOfSentencePunctuationMarkQuestion || 
				ch == GeneralEndOfSentencePunctuationMarkExclamation ||
				ch == GeneralEndOfSentencePunctuationMarkDot
				) return true;

			return false;
		}

    /// <summary>
    /// </summary>
    /// <param name="ch">character to check</param>
    /// <returns>true/false</returns>
    public override bool DoSkipCharInTerm(char ch)
    {
      if (ch >= ArabNotInRangeBegin_1 && ch <= ArabNotInRangeEnd_1) return true;
      if (ch >= ArabNotInRangeBegin_2 && ch <= ArabNotInRangeEnd_2) return true;
      if (ch == ArabQashida) return true;
      return false;
    }

    /// <summary>
    /// Normalization of the character
    /// Example: Capital letter convert to low
    /// </summary>
    /// <param name="ch">normalized character</param>
    /// <returns>char</returns>
    public override char Normalize(char ch)
    {
      if (ch == ArabLastLetterToReplace1 || 
        ch == ArabLastLetterToReplace2 ||
        ch == ArabLastLetterToReplace3) 
        return (char)ArabLastLetterReplaced1_2_3;
      else if (ch == ArabLastLetterToReplace4) 
        return (char)ArabLastLetterReplaced4;
      else if (ch == ArabLastLetterToReplace5) 
        return (char)ArabLastLetterReplaced5;

      else return ch;
    }

    public override string ToString()
    {
      return "Arab character filter";
    }
	}
}
